﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Threading;
using ConfrontaTracciati.CLASSI;
using System.Data.SqlClient;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data.OleDb;


namespace ConfrontaTracciati
{
    public partial class FrmMain : Form
    {
        private BackgroundWorker bw;
        private AutoResetEvent resetEvent;
        private delegate void AggiornaTextBox(string msg, bool newLine);
        private delegate void AggiornaProgressbar(bool visible, int min, int max, int val);

        private BackgroundWorker bw_Excel;
        private AutoResetEvent resetEvent_Excel;

        IList<ErrorStruct> m_RecordDuplicatiMirror = new List<ErrorStruct>();
        IList<ErrorStruct> m_RecordDuplicatiTarget = new List<ErrorStruct>();
        IList<ErrorStruct> m_RecordDuplicatiInTargetNonPresentiInMirror = new List<ErrorStruct>();
        IList<ErrorStruct> m_RecordDuplicatiInMirrorNonPresentiInTarget = new List<ErrorStruct>();

        private IList<Ctracciato>  m_TracList = null;
        Ctracciato m_Tracciato = null;
        CdbUtils Connessione = new CdbUtils();

        Queue<string> PathLocali = new Queue<string>(4);  // per la gestione del salvataggio degli ultimi 5 path usati
        Queue<string> PathRete = new Queue<string>(4);    // per la gestione del salvataggio degli ultimi 5 path usati

        bool ProceduraCompletaInEsecuzione = false;


    #region "Form MAIN"

        public FrmMain()
        {
            InitializeComponent();
            bw = new BackgroundWorker();
            bw.DoWork += bw_DoWork;
            bw.ProgressChanged += bw_ProgressChanged;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;

            resetEvent = new AutoResetEvent(false);

            bw_Excel = new BackgroundWorker();
            bw_Excel.DoWork += bw_Excel_DoWork;
            bw_Excel.ProgressChanged += bw_Excel_ProgressChanged;
            bw_Excel.RunWorkerCompleted += bw_Excel_RunWorkerCompleted;
            bw_Excel.WorkerReportsProgress = true;
            bw_Excel.WorkerSupportsCancellation = true;

            resetEvent_Excel = new AutoResetEvent(false);
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            try
            {
                if (Properties.Settings.Default.PathLocale_5 != string.Empty) PathLocali.Enqueue(Properties.Settings.Default.PathLocale_5);
                if (Properties.Settings.Default.PathLocale_4 != string.Empty) PathLocali.Enqueue(Properties.Settings.Default.PathLocale_4);
                if (Properties.Settings.Default.PathLocale_3 != string.Empty) PathLocali.Enqueue(Properties.Settings.Default.PathLocale_3);
                if (Properties.Settings.Default.PathLocale_2 != string.Empty) PathLocali.Enqueue(Properties.Settings.Default.PathLocale_2);
                if (Properties.Settings.Default.PathLocale_1 != string.Empty) PathLocali.Enqueue(Properties.Settings.Default.PathLocale_1);
                txtPathPC.Items.AddRange(PathLocali.ToArray());
                txtPathPC.Text = PathLocali.Peek();
                if (Properties.Settings.Default.PathRete_5 != string.Empty) PathRete.Enqueue(Properties.Settings.Default.PathRete_5);
                if (Properties.Settings.Default.PathRete_4 != string.Empty) PathRete.Enqueue(Properties.Settings.Default.PathRete_4);
                if (Properties.Settings.Default.PathRete_3 != string.Empty) PathRete.Enqueue(Properties.Settings.Default.PathRete_3);
                if (Properties.Settings.Default.PathRete_2 != string.Empty) PathRete.Enqueue(Properties.Settings.Default.PathRete_2);
                if (Properties.Settings.Default.PathRete_1 != string.Empty) PathRete.Enqueue(Properties.Settings.Default.PathRete_1);
                txtPathCondivisa.Items.AddRange(PathRete.ToArray());
                txtPathCondivisa.Text = PathRete.Peek();

                CConfiguratore.CaricaConfigurazioneTracciati("tracciati.xml", ref m_TracList);
                CaricaComboTracciati();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ATTENZIONE", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void CaricaComboTracciati()
        {
            cboTracciato.Items.Clear();
            foreach (Ctracciato tracc in m_TracList)
            {
                if (!cboTracciato.Items.Contains(tracc.Categoria)) this.cboTracciato.Items.Add(tracc.Categoria);
            }
        }

    #endregion "Form MAIN"

    #region "Background Worker - Carica Tracciati"

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            if (((BackgroundWorker)sender).CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            long cntTARGET = 0, cntMIRROR=0;
            string record = string.Empty, datiChiave = string.Empty;
            string fileName = string.Empty;
            
            Ctracciato tracciato = e.Argument as Ctracciato;
            if (tracciato == null)
            {
                MessageBox.Show("Istanza di classe Tracciato non trovata in caricamento file tracciati");
                return;
            }

            if (!ArpriChiudiConnessioneDB(true)) return;

            m_RecordDuplicatiMirror.Clear();
            m_RecordDuplicatiTarget.Clear();
            m_RecordDuplicatiInMirrorNonPresentiInTarget.Clear();
            m_RecordDuplicatiInTargetNonPresentiInMirror.Clear();

            AggiornaTextRisultati("Caricamento tracciato MIRROR in corso ... ", true);            

            SqlTransaction trans = null;
            using (trans = Connessione.Conn.BeginTransaction("CaricamentoFlussi"))
            {

                try
                {
                    fileName = Directory.GetFiles(tracciato.path_Dir_MIRROR).FirstOrDefault();
                    if (!File.Exists(fileName))
                    {
                        MessageBox.Show("Path file MIRROR da caricare NON trovato : \r\n'" + fileName + "'");
                        e.Cancel = true; 
                        return;
                    }

                    switch (System.IO.Path.GetExtension(fileName).ToLower())
                    {

                        case ".dbf":
                            cntMIRROR = CaricaTabellaDaFileDbf(ref trans, fileName, "_MIRROR", ref tracciato, ref m_RecordDuplicatiTarget, e, sender);
                            break;

                        default:
                            cntMIRROR = CaricaTabellaDaFileTxt(ref trans, fileName, "_MIRROR", ref tracciato, ref m_RecordDuplicatiTarget, e, sender);
                            break;

                    }  
                }
                catch (Exception ex)
                {
                    if (trans.Connection != null) trans.Rollback("CaricamentoFlussi");
                    e.Result = " NOT OK " + ex.Message;
                    throw ;                  
                }    
            }   

                //TARGET **************

                AggiornaTextRisultati("Caricamento tracciato TARGET in corso ... ", true);

                using (trans = Connessione.Conn.BeginTransaction("CaricamentoFlussi"))
                {
                    try
                    {

                        fileName = Directory.GetFiles(tracciato.path_Dir_TARGET).FirstOrDefault();//<<<TARGET
                        if (!File.Exists(fileName))
                        {
                            MessageBox.Show("Path file TARGET da caricare NON trovato : \r\n'" + fileName + "'");
                            e.Cancel = true;
                            return;
                        }

                        switch (System.IO.Path.GetExtension(fileName).ToLower())
                        {
                            case ".dbf":
                                //Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\folder;Extended Properties=dBASE IV;User ID=Admin;Password=;      
                                break;

                            default:
                                cntTARGET = CaricaTabellaDaFileTxt(ref trans, fileName, "_TARGET", ref tracciato, ref m_RecordDuplicatiTarget, e, sender);
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (trans.Connection != null) trans.Rollback("CaricamentoFlussi");
                        e.Result = " NOT OK " + ex.Message;
                        throw;
                    }
                }

                try
                {
                    var resList = m_RecordDuplicatiTarget.Select(x=> x.Record ).ToList();
                    m_RecordDuplicatiInMirrorNonPresentiInTarget = m_RecordDuplicatiMirror.Where(x => !resList.Contains(x.Record)).ToList();

                    resList = m_RecordDuplicatiMirror.Select(x => x.Record).ToList();
                    m_RecordDuplicatiInTargetNonPresentiInMirror = m_RecordDuplicatiTarget.Where(x => !resList.Contains(x.Record)).ToList();
                    
                }
                catch (Exception ex)
                {

                    throw;
                }

                string mex = string.Empty, mex_temp;
                mex_temp = "Tot Record caricati  in MIRROR : " + cntMIRROR;
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                mex_temp = "Tot Record caricati  in TARGET : " + cntTARGET;
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                mex_temp = "Tot Record duplicati in MIRROR : " + m_RecordDuplicatiMirror.Count();
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                mex_temp = "Tot Record duplicati in TARGET : " + m_RecordDuplicatiTarget.Count();
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                mex_temp = "Tot Record duplicati in MIRROR non presenti in Target : " + m_RecordDuplicatiInMirrorNonPresentiInTarget.Count();
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                mex_temp = "Tot Record duplicati in TARGET non presenti in Mirror : " + m_RecordDuplicatiInTargetNonPresentiInMirror.Count();
                mex += (mex_temp + "\r\n");
                AggiornaTextRisultati(mex_temp, true);
                    
                e.Result = new ResCaricamentoStruct(mex, m_RecordDuplicatiMirror, m_RecordDuplicatiTarget,
                    m_RecordDuplicatiInMirrorNonPresentiInTarget, m_RecordDuplicatiInTargetNonPresentiInMirror);
                                  
            }

        private int CaricaTabellaDaFileDbf(ref SqlTransaction trans, string fileName, string suffisso_tabella, ref Ctracciato tracciato,ref IList<ErrorStruct> m_RecordDuplicati, DoWorkEventArgs e, object sender)
        {
            OleDbConnection Conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + @"c:\ShareProva\tracciati\AUI\AIP\MIRROR\" + ";Extended Properties=dBASE IV;User ID=Admin;Password=;");
            try
            {
                Conn.Open();

                string query = "select * from " + fileName;

                //create an OleDbDataAdapter to execute the query
                OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, Conn);

                //create a command builder
                var cBuilder = new OleDbCommandBuilder(dAdapter);

                //create a DataTable to hold the query results
                var dt = new DataTable();
                dAdapter.Fill(dt);

            }
            catch (Exception ex) { throw ex; }

            // caricare i dati in tabella


            if (Conn.State == ConnectionState.Open) Conn.Close();

            return 0;

        }


        private int CaricaTabellaDaFileTxt(ref SqlTransaction trans, string fileName, string suffisso_tabella, ref Ctracciato tracciato, ref IList<ErrorStruct> m_RecordDuplicati, DoWorkEventArgs e, object sender)
        {
            string record = string.Empty, datiChiave = string.Empty;
            int cnt = 0;


            using (StreamReader sr = new StreamReader(fileName))
            {
                AggiornaProgbar(true, 0, File.ReadAllLines(fileName).Length, 0);

                //Debug.WriteLine(DateTime.Now);
                while (!sr.EndOfStream)
                {
                    if (((BackgroundWorker)sender).CancellationPending)
                    {
                        trans.Rollback("CaricamentoFlussi");
                        e.Cancel = true;
                        return cnt;
                    }

                    cnt++;
                    record = sr.ReadLine();

                    if (tracciato.UsaChiave)
                        datiChiave = Ctracciato.getDatiChiave(tracciato.Chiave, record);

                    try
                    {
                        Connessione.CaricaTabella(tracciato.nome_tabella + suffisso_tabella, datiChiave, record, ref trans);
                    }
                    catch (System.Data.ConstraintException conEx)
                    {
                        m_RecordDuplicati.Add(new ErrorStruct(cnt, record, null, conEx.Message));
                    }
                    catch (System.Data.DuplicateNameException dupEx)
                    {
                        m_RecordDuplicati.Add(new ErrorStruct(cnt, record, null, dupEx.Message));
                    }
                    catch (System.Data.SqlClient.SqlException  sqlEx)
                    {
                        m_RecordDuplicati.Add(new ErrorStruct(cnt, record, null, sqlEx.Message));
                    }

                    if (cnt % 100 == 0)
                    {
                        ((BackgroundWorker)sender).ReportProgress(m_RecordDuplicati.Count, cnt);
                        resetEvent.WaitOne();
                    }
                }
            }

            ((BackgroundWorker)sender).ReportProgress(m_RecordDuplicati.Count, cnt);
            resetEvent.WaitOne();

            trans.Commit();
            AggiornaTextRisultati("OK (" + cnt + ")", false);
            return cnt;    
        }


        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripStatusLabel.Text = e.UserState.ToString() + " (duplicati: " + e.ProgressPercentage + ")";
            AggiornaProgbar(true, 0, -1, (int)e.UserState);
            resetEvent.Set();
        }

        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RunningMode(false);
            AggiornaProgbar(false, 0, 0, 0);

            AggiornaTextRisultati("Chiusura connessione in corso ... ", true);
            Connessione.ChiudiConnessione();
            AggiornaTextRisultati("OK", false);

            if (e.Cancelled)
            {
                toolStripStatusLabel.Text = "Elaborazione interrotta";
                
                MessageBox.Show("Elaborazione interrotta", "ATTENZIONE", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            string msg=string.Empty ;

            if (e.Error != null)
            {
                msg = " con errori : " + e.Error.Message;
                AggiornaTextRisultati(msg, true);
                toolStripStatusLabel.Text = msg;
                
                return;
            }
                        
            var res = (ResCaricamentoStruct)e.Result;

            dataG_Mirror.DataSource = null;
            this.dataG_Mirror.DataSource = res.ErrateMirror;
            this.dataG_Mirror.Refresh();

            dataG_Target.DataSource = null;
            this.dataG_Target.DataSource = res.ErrateTarget;
            this.dataG_Target.Refresh();

            res.RecordErratiNonCombaciantiInMirror.ToList().AddRange(res.RecordErratiNonCombaciantiInTarget);

            dataGNonCombacianti.DataSource = null;
            this.dataGNonCombacianti.DataSource = res.RecordErratiNonCombaciantiInMirror;
            this.dataGNonCombacianti.Refresh();

            if (ProceduraCompletaInEsecuzione)
            {                
                ConfrontaTracciati();
                ProceduraCompletaInEsecuzione = false;
            }

            toolStripStatusLabel.Text = "Caricamento Tracciati terminato";
            
        }

    #endregion "Background Worker - Carica Tracciati"

    #region "Crea-Svuota Tabelle"

        private void creaTabellaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreaTabella();
        }

        private void cmdCreaTabella_Click(object sender, EventArgs e)
        {
            CreaTabella();
        }

        private void CreaTabella()
        {
            try
            {
                txtRisultato.Clear();

                if (!ArpriChiudiConnessioneDB(true)) return;

                if (Connessione.CreaTabella(m_Tracciato) == -2)
                {
                    AggiornaTextRisultati("Creata la tabella " + txtNomeTabella.Text + "_TARGET", true);
                    AggiornaTextRisultati("Creata la tabella " + txtNomeTabella.Text + "_MIRROR", true);
                }
                else
                {
                    AggiornaTextRisultati("Errore creazione tabelle", true);
                }

                ArpriChiudiConnessioneDB(false);
                
            }
            catch (Exception ex)
            {
                AggiornaTextRisultati("Errore creazione tabelle: [" + ex.Message + "]", true);
            }
        }

        private void cmdSvuotaTabella_Click(object sender, EventArgs e)
        {
            SvuotaTabella();
        }

        private void svuotaTabellaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SvuotaTabella();
        }

        private void SvuotaTabella()
        {
            try
            {
                if (!ArpriChiudiConnessioneDB(true)) return;

                if (Connessione.SvuotaTabella(txtNomeTabella.Text) == -2)
                {
                    AggiornaTextRisultati("Svuota tabelle effettuato", true);
                }
                else
                {
                    AggiornaTextRisultati("Errore svuota tabelle", true);
                }
                ArpriChiudiConnessioneDB(false);
            }
            catch (Exception ex)
            {
                AggiornaTextRisultati("Errore svuota tabelle: [" + ex.Message + "]", true);
            }
        }

    #endregion "Crea-Svuota Tabelle"

    #region "Funzioni Base"

        private void AggiornaProgbar(bool visible, int min, int max, int val)
        {
            if (InvokeRequired)
            {
                Invoke(new AggiornaProgressbar(AggiornaProgbar), new object[] { visible, min, max, val });
                return;
            }
            toolStripProgressBar.Visible = visible;
            toolStripProgressBar.Minimum = min;
            if (max > 0) toolStripProgressBar.Maximum = max;
            if (val >= min && val <= toolStripProgressBar.Maximum) toolStripProgressBar.Value = val;
        }

        private void AggiornaTextRisultati(string msg, bool newLine)
        {
            if (InvokeRequired)
            {
                Invoke(new AggiornaTextBox(AggiornaTextRisultati), new object[] { msg, newLine });
                return;
            }

            if (newLine)
                txtRisultato.AppendText("\r\n" + DateTime.Now + "    " + msg);
            else
                txtRisultato.AppendText(msg);
        }

        private bool ArpriChiudiConnessioneDB(bool bOpen)
        {
            bool ret = false;

            if (bOpen)
            {
                AggiornaTextRisultati("Apertura connessione ... ", true);
                ret = Connessione.ApriConnessione();
                if (ret)
                {
                    AggiornaTextRisultati("OK", false);
                }
                else
                {
                    AggiornaTextRisultati("KO", false);
                }
            }
            else
            {
                AggiornaTextRisultati("Chiusura connessione ... ", true);
                ret = Connessione.ChiudiConnessione();
                if (ret)
                {
                    AggiornaTextRisultati("OK", false);
                }
                else
                {
                    AggiornaTextRisultati("KO", false);
                }
            }
            return (ret);
        }//fM

        private string getPathBase()
        {
            if (radioPC.Checked)
            {
                return txtPathPC.Text;
            }
            else
            {
                return txtPathCondivisa.Text;
            }
        }

        // Se in running disabilito i controlli
        private void RunningMode(bool bRunning)
        {
            if (bRunning)
            {               
                foreach (Control item in grpGenerale.Controls)
                {
                    try { item.Enabled = false; }
                    catch { }
                }
                try { grpTracciati.Enabled = true; }
                catch { }
                
                foreach (Control item in grpTracciati.Controls)
                {
                    try { item.Enabled = false; }
                    catch { }
                }
                try { cmdStopCaricaTracciati.Enabled = true; Cursor = Cursors.WaitCursor; }
                catch { }

                               
            }
            else
            {
                foreach (Control item in grpGenerale.Controls)
                {
                    try { item.Enabled = true; }
                    catch { }
                }
                foreach (Control item in grpTracciati.Controls)
                {
                    try { item.Enabled = true; }
                    catch { }
                }

                try { if (!ProceduraCompletaInEsecuzione) grpGenerale.Enabled = true; Cursor = Cursors.Default; }
                catch { }
                                
            }
        }

        private void CaricaTracciati()
        {
            try
            {
                string fileMIRROR = Directory.GetFiles(m_Tracciato.path_Dir_MIRROR).FirstOrDefault();
                string fileTARGET = Directory.GetFiles(m_Tracciato.path_Dir_TARGET).FirstOrDefault();

                RunningMode(true);

                SvuotaTabella();

                var path = Path.Combine(m_Tracciato.path_Dir_RES, "Orig");
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);

                if (File.Exists(fileMIRROR))
                    File.Copy(fileMIRROR, Path.Combine(path, "MIRROR_" + Path.GetFileName(fileMIRROR)), true);

                if (File.Exists(fileTARGET))
                    File.Copy(fileTARGET, Path.Combine(path, "TARGET_" + Path.GetFileName(fileTARGET)), true);

                bw.RunWorkerAsync(m_Tracciato);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Errore caricamento tracciati: " + ex.Message, "ATTENZIONE", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ConfrontaTracciati()
        {
            try
            {
                grpGenerale.Enabled = false;

                AggiornaTextRisultati("Confronto tabelle in corso ... ", true);

                m_Tracciato.path_file_MIRROR = Directory.GetFiles(m_Tracciato.path_Dir_MIRROR).FirstOrDefault();
                if (m_Tracciato.path_file_MIRROR.Length == 0)
                {
                    MessageBox.Show("Manca il file nella cartella MIRROR "); return;
                }

                m_Tracciato.path_file_TARGET = Directory.GetFiles(m_Tracciato.path_Dir_TARGET).FirstOrDefault();
                if (m_Tracciato.path_file_TARGET.Length == 0)
                {
                    MessageBox.Show("Manca il file nella cartella TARGET "); return;
                }

                AggiornaTextRisultati("FILE DA CONFRONTARE: ", true);
                AggiornaTextRisultati(m_Tracciato.path_file_MIRROR, true);
                AggiornaTextRisultati(m_Tracciato.path_file_TARGET, true);
                AggiornaTextRisultati("CHIAVE TRACCIATI = " + m_Tracciato.Chiave, true);

                if (!ArpriChiudiConnessioneDB(true)) return;

                if (Connessione.ConfrontaTabella(ref m_Tracciato) == -1)
                {
                    AggiornaTextRisultati("CONFRONTO TABELLE TERMINATO", true);
                    AggiornaTextRisultati("Tot Record orfani : " + m_Tracciato.Orfane, true);
                    AggiornaTextRisultati("Tot Record errati : " + m_Tracciato.Errate, true);
                }
                else
                {
                    AggiornaTextRisultati("Errore confronto tabelle", true);
                }

                ArpriChiudiConnessioneDB(false);

                GeneraReportExcel();
            }
            catch (Exception ex)
            {
                AggiornaTextRisultati("Errore confronto tabelle: [" + ex.Message + "]", true);
            }
            finally
            {
               if (!ProceduraCompletaInEsecuzione) grpGenerale.Enabled = true;
            }
        }

        private void AggiungiPath(bool pLocale)
        {
            if (pLocale)
            {
                if (!PathLocali.Contains(txtPathPC.Text))
                {
                    txtPathPC.Items.Add(txtPathPC.Text);
                    PathLocali.Dequeue();
                    PathLocali.Enqueue(txtPathPC.Text);
                    int numPath = PathLocali.Count;
                    string[] pLocali = PathLocali.ToArray();
                    Properties.Settings.Default.PathLocale_1 = pLocali[0];
                    if (numPath - 1 > 0) Properties.Settings.Default.PathLocale_2 = pLocali[1]; // PathLocali.Peek();//PathLocali[numPath - 2];
                    if (numPath - 2 > 0) Properties.Settings.Default.PathLocale_3 = pLocali[2]; //PathLocali.Peek();//PathLocali[numPath - 3];
                    if (numPath - 3 > 0) Properties.Settings.Default.PathLocale_4 = pLocali[3]; //PathLocali.Peek();//PathLocali[numPath - 4];
                    if (numPath - 4 > 0) Properties.Settings.Default.PathLocale_5 = pLocali[4]; //PathLocali.Peek();//PathLocali[numPath - 5];
                    Properties.Settings.Default.Save();
                }
            }
            else
            {
                if (!PathRete.Contains(txtPathCondivisa.Text))
                {
                    txtPathCondivisa.Items.Add(txtPathCondivisa.Text);
                    PathRete.Dequeue();
                    PathRete.Enqueue(txtPathCondivisa.Text);
                    int numPath = PathRete.Count;
                    string[] pRete = PathLocali.ToArray();
                    Properties.Settings.Default.PathRete_1 = pRete[0];
                    if (numPath - 1 > 0) Properties.Settings.Default.PathRete_2 = pRete[1];
                    if (numPath - 2 > 0) Properties.Settings.Default.PathRete_3 = pRete[2];
                    if (numPath - 3 > 0) Properties.Settings.Default.PathRete_4 = pRete[3];
                    if (numPath - 4 > 0) Properties.Settings.Default.PathRete_5 = pRete[4];
                    Properties.Settings.Default.Save();
                }

            }
        }

    #endregion "Funzioni Base"

    #region "Report Excel"

        #region "BW Report Excel"

            private void bw_Excel_DoWork(object sender, DoWorkEventArgs e)
            {
                Excel.Application xlApp;
                Excel.Workbook xlWorkBook;
                xlApp = new Excel.ApplicationClass();
                //xlApp.DisplayAlerts = false;
                xlWorkBook = xlApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
                object misValue = System.Reflection.Missing.Value;
                DataTable dt = new DataTable();
                List<string> lista_fogli_da_eliminare = new List<string>();

                RunningMode(true);

                if (((BackgroundWorker)sender).CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                try
                {

                    foreach (Excel.Worksheet item in xlWorkBook.Sheets)
                    {
                        lista_fogli_da_eliminare.Add(item.Name);
                    }

                    if (fogliOriginaliMIRRORETARGETToolStripMenuItem.Checked || reportCompletoToolStripMenuItem.Checked)
                    {
                        // TARGET
                        AggiungiFoglioExcel(ref xlWorkBook, "TARGET", "#", Connessione.LeggiTabella(m_Tracciato.nome_tabella + "_TARGET"));

                        // MIRROR
                        AggiungiFoglioExcel(ref xlWorkBook, "MIRROR", "#", Connessione.LeggiTabella(m_Tracciato.nome_tabella + "_MIRROR"));
                    }

                    if (fogliDuplicateNonTrovateToolStripMenuItem.Checked || reportCompletoToolStripMenuItem.Checked)
                    {
                        // duplicate NON TROVATE TARGET
                        AggiungiFoglioExcel(ref xlWorkBook, "DUPL_NON_TROVATE_TARGET", "#", m_RecordDuplicatiInTargetNonPresentiInMirror);

                        // duplicate NON TROVATE MIRROR
                        AggiungiFoglioExcel(ref xlWorkBook, "DUPL_NON_TROVATE_MIRROR", "#", m_RecordDuplicatiInMirrorNonPresentiInTarget);
                    }

                    if (fogliDUPLICATEToolStripMenuItem.Checked || reportCompletoToolStripMenuItem.Checked)
                    {
                        // duplicate TARGET
                        AggiungiFoglioExcel(ref xlWorkBook, "DUPL_TARGET", "#", m_RecordDuplicatiTarget);

                        // duplicate MIRROR
                        AggiungiFoglioExcel(ref xlWorkBook, "DUPL_MIRROR", "#", m_RecordDuplicatiMirror);
                    }

                    if (foglioORFANEToolStripMenuItem.Checked || reportCompletoToolStripMenuItem.Checked)
                    {
                        // ORFANE
                        AggiungiFoglioExcel(ref xlWorkBook, "ORFANE", "#", Connessione.LeggiTabella(m_Tracciato.nome_tabella + "_RES_ORFANE"));
                    }

                    if (foglioERRATEToolStripMenuItem.Checked || reportCompletoToolStripMenuItem.Checked)
                    {
                        // ERRATE
                        AggiungiFoglioExcel(ref xlWorkBook, "ERRATE", "#", Connessione.LeggiTabella(m_Tracciato.nome_tabella + "_RES_ERRATE"));
                    }

                    AggiungiFoglioExcel(ref xlWorkBook, "Risultato", "@", txtRisultato.Text);

                    foreach (string foglio in lista_fogli_da_eliminare)
                    {
                        ((Excel.Worksheet)xlWorkBook.Sheets[foglio]).Delete();
                    }


                    if (bw_Excel.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    xlWorkBook.SaveAs(Path.Combine(m_Tracciato.path_Dir_RES, "Report_" + m_Tracciato.nome_tabella + ".xls"), misValue,
                                      misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);

                }

                catch (Exception ex)
                {
                    e.Result = "Errore generazione file Excel";
                    if (ex.Source != "Microsoft.Office.Interop.Excel") e.Result += ": " + ex.Message;
                    //throw;
                }
                finally
                { 
                    xlWorkBook.Close(null, null, null);
                    xlApp.Workbooks.Close();
                    xlApp.Quit();

                    releaseObject(xlWorkBook);
                    releaseObject(xlApp);                
                }
            }

            private void bw_Excel_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                toolStripStatusLabel.Text = e.ProgressPercentage.ToString() + " di " + e.UserState.ToString() + " (" + (int)((int)e.ProgressPercentage * 100 / (int)e.UserState) + " %)";
                
                AggiornaProgbar(true, 0, (int)e.UserState, e.ProgressPercentage);
                resetEvent_Excel.Set();
            }

            private void bw_Excel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RunningMode(false);
            AggiornaProgbar(false, 0, 0, 0);

            if (e.Cancelled)
            {
                toolStripStatusLabel.Text = "Generazione report Excel interrotta";
                
                MessageBox.Show("Generazione report Excel interrotta", "ATTENZIONE", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            string msg = string.Empty;

            if (e.Result != null)
            {
                msg = e.Result.ToString(); // Error.Message;
                toolStripStatusLabel.Text = msg;
                
                AggiornaTextRisultati(msg, true);
                return;
            }

            toolStripStatusLabel.Text = "Generazione report Excel completata";
            
        }

        #endregion "BW Report Excel"

        private void GeneraReportExcel()
        {
            grpGenerale.Enabled = false;
            bw_Excel.RunWorkerAsync();
        }

        private void RiempiFoglioDaDataTable(DataTable dt, Excel.Worksheet ws)
        {
            int colIndex = 0;
            int rowIndex = 1;
            string cellText = null;

            foreach (DataColumn dc in dt.Columns)
            {
                colIndex = colIndex + 1;
                ws.Cells[rowIndex, colIndex] = dc.ColumnName;
            }

            foreach (DataRow dr in dt.Rows)
            {
                rowIndex = rowIndex + 1;
                colIndex = 0;

                foreach (DataColumn dc in dt.Columns)
                {
                    colIndex = colIndex + 1;
                    cellText = dr[dc.ColumnName].ToString();
                    // Check for null cell and change it to empty to avoid error
                    if (cellText == string.Empty) cellText = "";
                    ws.Cells[rowIndex, colIndex] = cellText;
                }
                if (rowIndex % 100 == 0)
                {
                    bw_Excel.ReportProgress(rowIndex, dt.Rows.Count);
                    resetEvent_Excel.WaitOne();
                }
                if (bw_Excel.CancellationPending)
                {
                    return;
                }
            }
        }

        private void interrompiReportExcelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bw_Excel.CancelAsync();
        }

        private void RiempiFoglioDaTextMultiLine(string text, Excel.Worksheet ws)
        {
            string[] linee = text.Split(new[] { "\r\n" }, System.StringSplitOptions.None);
            for (int riga = 0; riga < linee.Length; riga++)
			{
			    ws.Cells[riga+1, 1] = linee[riga];
			}
        }//fM

        private void RiempiFoglioDaLista(IList<ErrorStruct> lista, Excel.Worksheet ws)
        {

            int rowIndex = 1;            

            //Write the column names
            ws.Cells[rowIndex, 1] = string.Format("Numero record");
            ws.Cells[rowIndex, 2] = string.Format("Record");
            ws.Cells[rowIndex, 3] = string.Format("Errore");
            foreach (var item in lista)
            {
                rowIndex = rowIndex + 1;                
                ws.Cells[rowIndex, 1] = item.RecordNumber.ToString();
                ws.Cells[rowIndex, 2] = item.Record;
                ws.Cells[rowIndex, 3] = item.ErrorMessage.Replace("\r\n", "\t");
            }
        }//fM

        private void exportDataTableToExcel(DataTable dt, string filePath)
        {

            //  Excel file Path

            int colIndex = 0;
            int rowIndex = 0;

            // Open the file and write the headers
            StreamWriter fs = new StreamWriter(filePath, false);

            colIndex = 0;
            string line = string.Empty;
            //Write the column names
            foreach (DataColumn dc in dt.Columns)
            {
                colIndex = colIndex + 1;
                line += string.Format(" " + "{0}", dc.ColumnName) + "\t";
            }
            fs.WriteLine(line);


            // Write contents for each cell      
            string cellText = null;
            foreach (DataRow dr in dt.Rows)
            {
                rowIndex = rowIndex + 1;
                colIndex = 0;

                line = string.Empty;
                foreach (DataColumn dc in dt.Columns)
                {
                    colIndex = colIndex + 1;
                    cellText = dr[dc.ColumnName].ToString();
                    // Check for null cell and change it to empty to avoid error
                    if (cellText == string.Empty) cellText = "";
                    line += string.Format(" " + "{0}", cellText.ToString()) + "\t";
                }
                fs.WriteLine(line);
            }

            fs.Close();

        }

        private void exportDataTableToExcel(IList<ErrorStruct> lista, string filePath)
        {

            //  Excel file Path

            int rowIndex = 0;

            // Open the file and write the headers
            StreamWriter fs = new StreamWriter(filePath, false);

            rowIndex = 0;
            string line = string.Empty;
            //Write the column names
            line = string.Format(" " + "Numero record\tRecord\tErrore");
            fs.WriteLine(line);
            foreach (var item in lista)
            {
                rowIndex = rowIndex + 1;
                line = string.Format(" " + "{0}\t{1}\t{2}", item.RecordNumber, item.Record, item.ErrorMessage.Replace("\r\n", "\t"));
                fs.WriteLine(line);
            }

            fs.Close();
        }

        private void AggiungiFoglioExcel(ref Excel.Workbook wb,string nome_foglio, string formato, object data)
        {
            if (bw_Excel.CancellationPending)
            {
                return;
            }

            AggiornaTextRisultati("Creazione foglio " + nome_foglio + " in corso ...", true);

            object misValue = System.Reflection.Missing.Value;
            Excel.Range oRng;
            Excel.Worksheet xlWorkSheet = (Excel.Worksheet)wb.Worksheets.Add(misValue, misValue, misValue, misValue);

            xlWorkSheet.Cells.NumberFormat = formato;
            xlWorkSheet.Cells.Font.Name = "Consolas";
            xlWorkSheet.Name = nome_foglio;

            if (data is DataTable)
                RiempiFoglioDaDataTable(data as DataTable, xlWorkSheet);            
            else if (data is string)
                RiempiFoglioDaTextMultiLine(data as string, xlWorkSheet);
            else
                RiempiFoglioDaLista(data as IList<ErrorStruct>, xlWorkSheet);

            oRng = xlWorkSheet.get_Range("A1", "Z1");
            oRng.Font.Bold = true;
            xlWorkSheet.Cells.EntireColumn.AutoFit();

            releaseObject(oRng);
            releaseObject(xlWorkSheet);
            AggiornaTextRisultati("OK", false);
        }//fM

        private void releaseObject(object obj)
        {
            try
            {
                while (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) != 0)
                {
                    Thread.Sleep(500);
                }
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }

        }//fM
    
    #endregion "Report Excel"

    #region "Eventi dei Controlli"

        private void cboTracciato_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.cmbSottoTracciati.Items.Clear();
            IEnumerable<Ctracciato> sotto_trac = m_TracList.Where(x => (x.Categoria == cboTracciato.Text)); // .ToList<Ctracciato>;
            this.cmbSottoTracciati.Items.AddRange(sotto_trac.Select(x => x.nome_tracciato).ToArray());
            if (this.cmbSottoTracciati.Items.Count > 0) this.cmbSottoTracciati.Text = this.cmbSottoTracciati.Items[0].ToString();
        }

        private void cmbSottoTracciati_SelectedIndexChanged(object sender, EventArgs e)
        {
             var trac1 = cmbSottoTracciati.SelectedItem ;
            if (trac1 == null) return;
            string trac = trac1.ToString() ;

            m_Tracciato = m_TracList.Where(x => x.nome_tracciato == trac && x.Categoria == cboTracciato.Text).FirstOrDefault();

            CConfiguratore.creaAlberaturaCartelle(getPathBase(), ref m_Tracciato);
            
            txtNomeTabella.Text = m_Tracciato.nome_tabella;
            txtTracciatoOld.Text = m_Tracciato.path_Dir_MIRROR;
            txtTracciatoUni.Text = m_Tracciato.path_Dir_TARGET;
            txtTracciatoRes.Text = m_Tracciato.path_Dir_RES;

        }//fm

        private void cmdSfogliaOld_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowNewFolderButton = true;
            folderBrowserDialog1.SelectedPath = txtTracciatoOld.Text;
            DialogResult res = folderBrowserDialog1.ShowDialog();
            if (res == DialogResult.OK)
                txtTracciatoOld.Text = folderBrowserDialog1.SelectedPath;
        }//fM
        private void cmdSfogliaUni_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowNewFolderButton = true;
            folderBrowserDialog1.SelectedPath = txtTracciatoUni.Text;
            DialogResult res = folderBrowserDialog1.ShowDialog();
            if (res == DialogResult.OK)
                txtTracciatoUni.Text = folderBrowserDialog1.SelectedPath;
        }//fM
        private void cmdSfogliaPathLocale_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowNewFolderButton = true;
            folderBrowserDialog1.SelectedPath = txtPathPC.Text;
            DialogResult res = folderBrowserDialog1.ShowDialog();
            if (res == DialogResult.OK)
            {
                txtPathPC.Text = folderBrowserDialog1.SelectedPath;
                AggiungiPath(true);
            }
        }//fM
        private void cmdSfogliaPathRete_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowNewFolderButton = true;
            folderBrowserDialog1.SelectedPath = txtPathCondivisa.Text;
            DialogResult res = folderBrowserDialog1.ShowDialog();
            if (res == DialogResult.OK)
            {
                txtPathCondivisa.Text = folderBrowserDialog1.SelectedPath;
                AggiungiPath(false);
            }
        }//fM

        private void cmdApriCartellaRES_Click(object sender, EventArgs e)
        {
            Process.Start(txtTracciatoRes.Text);
        }

        private void confrontaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfrontaTracciati();
        }

        private void generaReportExcelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GeneraReportExcel();
        }

        private void foglioToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menu = sender as ToolStripMenuItem;
            menu.Checked = !menu.Checked;
        }

        private void cmdCaricaTracciati_Click(object sender, EventArgs e)
        {
            CaricaTracciati();
        }
        private void caricaTracciatiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CaricaTracciati();
        }

        private void cmdStopCaricaTracciati_Click(object sender, EventArgs e)
        {
            bw.CancelAsync();            
        }
        private void interrompiCaricamentoTracciatiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bw.CancelAsync();            
        }

        private void eseguiProceduraCompletaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProceduraCompletaInEsecuzione = true;
            CreaTabella();
            CaricaTracciati();            
        }

        private void cboPathPC_Leave(object sender, EventArgs e)
        {
            AggiungiPath(true);
        }
    
        private void configuraTracciatiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmConfiguratore frm = new FrmConfiguratore(ref m_TracList);
            frm.ShowDialog();
            CaricaComboTracciati();
        }
    
    #endregion "Eventi dei Controlli"


        

 
















    }//fF
}//fC
